$ver = $host | select version
if ($ver.Version.Major -gt 1)  {$Host.Runspace.ThreadOptions = "ReuseThread"}

# Loading SharePoint snapin

Add-PsSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
Import-Module WebAdministration -ErrorAction SilentlyContinue

Write-Progress -Activity "Creating Web Application" -Status "Setting up variables"

# Setting up variables 

$WebApplicationName = "SharePoint - 7890"
$WebApplicationURL = "http://s-ps1:7890"
$HTTPPort = 7890
$HostHeader = "http://s-ps1"
$ApplicationPoolDisplayName = "SharePoint - 7890"
$ApplicationPoolIdentity = "sp2013\sp-pool"
$ApplicationPoolPassword = "pass@word1"
$ContentDatabase = "Contoso_ContentDB13"
$PortalSuperReader = "sp2013\sp-reader"
$PortalSuperUser = "sp2013\sp-user"

$FatalError = $False
$AppPoolType = $False
Write-Progress -Activity "Creating Web Application" -Status "Checking if Web Application Already Exists"

if(Get-SPWebApplication $WebApplicationURL -ErrorAction SilentlyContinue)
{
    # If a web application with the specifid URL already exists, exit
    Write-Progress -Activity "Creating Web Application" -Status "There is already a Web Application on $WebApplicationURL. Aborting."
    Set-Variable -Name FatalError -Value $True -scope "script"
    sleep 5
    Write-Host "Error: There is already a Web Application on $WebApplicationURL" -ForegroundColor Red
}
elseif(Get-SPWebApplication $WebApplicationName -ErrorAction SilentlyContinue)
{
    # If a web application with the specifid name already exists, exit
    Write-Progress -Activity "Creating Web Application" -Status "There is already a Web Application with name $WebApplicationName. Aborting."
    Set-Variable -Name FatalError -Value $True -scope "script"
    sleep 5
    Write-Host "Error: There is already a Web Application with $WebApplicationName" -ForegroundColor Red
}
elseif(Get-SPContentDatabase $ContentDatabase -ErrorAction SilentlyContinue)
{
    # If a web application with the specifid name already exists, exit
    Write-Progress -Activity "Creating Web Application" -Status "There is already a Content Database with name $ContentDatabase. Aborting."
    Set-Variable -Name FatalError -Value $True -scope "script"
    sleep 5
    Write-Host "Error: There is already a Content Datbase with name $ContentDatabase" -ForegroundColor Red
}
else
{
    Write-Progress -Activity "Creating Web Application" -Status "Checking if Application Pool Already Exists"

    # Check to see if the specified application pool already exists. If it exists, use the existing app pool
    if($AppPool = Get-SPServiceApplicationPool $ApplicationPoolDisplayName -ErrorAction SilentlyContinue)
    {
        Write-Progress -Activity "Creating Web Application" -Status "Re-Using Existing SharePoint Application Pool"
        Set-Variable -Name AppPoolType -Value "SharePoint" -scope "script"
    }
    else
    {
        if((Test-Path IIS:\AppPools\$ApplicationPoolDisplayName).tostring() -eq "True")
        {
           Write-Progress -Activity "Creating Web Application" -Status "Application Pool with name $ApplicationPoolDisplayName exists and is not used by SharePoint"
           Set-Variable -Name AppPoolType -Value "NonSharePoint" -scope "script"
        }
    }

    if ($AppPoolType -eq $False)
    {
        Write-Progress -Activity "Creating Web Application" -Status "Creating Application Pool"
        
        # Since we have to create a new application pool, check to see if the account specified is already a managed account
        if(Get-SPManagedAccount $ApplicationPoolIdentity)
        {
            # If the specified account is already a managed account, use that account when creating a new application pool
            Set-Variable -Name AppPoolManagedAccount -Value (Get-SPManagedAccount $ApplicationPoolIdentity | select username) -scope "Script"
            Set-Variable -Name AppPool -Value (New-SPServiceApplicationPool -Name $ApplicationPoolDisplayName -Account $ApplicationPoolIdentity) -scope "Script"
        }
        else
        {
            # If the specified account is not already a managd account create a managed account using the credentials provided
            $AppPoolCredentials = New-Object System.Management.Automation.PSCredential $ApplicationPoolIdentity, (ConvertTo-SecureString $ApplicationPoolPassword -AsPlainText -Force)
            Set-Variable -Name AppPoolManagedAccount -Value (New-SPManagedAccount -Credential $AppPoolCredentials) -scope "Script"
            
            # Create an application pool using the new managed account
            Set-Variable -Name AppPool -Value (New-SPServiceApplicationPool -Name $ApplicationPoolDisplayName -Account (get-spmanagedaccount $ApplicationPoolIdentity)) -scope "Script"            
        }

        Write-Progress -Activity "Creating Web Application" -Status "Creating Web Application $WebapplicationURL"
        #Create a new web application using the existing parameters, assign it to the WebApp variable such that object cache user accounts can be configured
        #$WebApp = New-SPWebApplication -ApplicationPool $ApplicationPoolDisplayName -ApplicationPoolAccount (Get-SPManagedAccount $ApplicationPoolIdentity) -Name $WebApplicationName -url $WebApplicationURL -port $HTTPPort -DatabaseName $ContentDatabase -HostHeader $hostHeader -AuthenticationProvider (New-SPAuthenticationProvider)
        $WebApp = New-SPWebApplication -ApplicationPool $ApplicationPoolDisplayName -ApplicationPoolAccount (Get-SPManagedAccount $ApplicationPoolIdentity) -Name $WebApplicationName -url $WebApplicationURL -DatabaseName $ContentDatabase -AuthenticationProvider (New-SPAuthenticationProvider)

    }

    if($AppPoolType -eq "NonSharePoint")
    {
        Write-Host "Aborting: Application Pool $ApplicationPoolDisplayName already exists on the server and is not a SharePoint Application Pool" -ForegroundColor Red
        Write-Progress -Activity "Creating Web Application" -Status "Aborting: SharePoint Cannot use the specified Application Pool"
        Set-Variable -Name FatalError -Value $True -scope "script"
    }
    elseif($AppPoolType -eq "SharePoint")
    {
        # Grab the existing application pool, assign it to the AppPool variable
        Set-Variable -Name AppPool -Value (Get-SPServiceApplicationPool $ApplicationPoolDisplayName) -scope "script"

        Write-Progress -Activity "Creating Web Application" -Status "Creating Web Application $WebapplicationURL"
        #Create a new web application using the existing parameters, assign it to the WebApp variable such that object cache user accounts can be configured
        #$WebApp = New-SPWebApplication -ApplicationPool $ApplicationPoolDisplayName -Name $WebApplicationName -url $WebApplicationURL -port $HTTPPort -DatabaseName $ContentDatabase -HostHeader $hostHeader -AuthenticationProvider (New-SPAuthenticationProvider)
        $WebApp = New-SPWebApplication -ApplicationPool $ApplicationPoolDisplayName -ApplicationPoolAccount $ApplicationPoolIdentity -Name $WebApplicationName -url $WebApplicationURL -DatabaseName $ContentDatabase -AuthenticationProvider (New-SPAuthenticationProvider)
    }
    
    if (!$FatalError)
    {
        Write-Progress -Activity "Creating Web Application" -Status "Configuring Object Cache Accounts"
        
        #Assign Object Cache Accounts
        $WebApp.Properties["portalsuperuseraccount"] = $PortalSuperUser
        $WebApp.Properties["portalsuperreaderaccount"] = $PortalSuperReader
        
        Write-Progress -Activity "Creating Web Application" -Status "Creating Object Cache User Policies for Web Application"
        
        #Create a New Policy for the Super User
        $SuperUserPolicy = $WebApp.Policies.Add($PortalSuperUser, "Portal Super User Account")
        #Assign Full Control To the Super User
        $SuperUserPolicy.PolicyRoleBindings.Add($WebApp.PolicyRoles.GetSpecialRole([Microsoft.SharePoint.Administration.SPPolicyRoleType]::FullControl))

        #Create a New Policy for the Super Reader
        $SuperReaderPolicy = $WebApp.Policies.Add($PortalSuperReader, "Portal Super Reader Account")
        #Assign Full Read to the Super Reader
        $SuperReaderPolicy.PolicyRoleBindings.Add($WebApp.PolicyRoles.GetSpecialRole([Microsoft.SharePoint.Administration.SPPolicyRoleType]::FullRead))
        
        Write-Progress -Activity "Creating Web Application" -Status "Updating Web Application Properties"
    }
}